package FIT::Fixture::Runner;

use FIT::Class;
use FIT::Document::Transformer;
use aliased 'FIT::Fixture::Factory';

has fixture_factory => (
    is       => 'ro',
    isa      => 'FIT::Fixture::Factory',
    required => 1,
    handles  => [qw( make_fixture )],
    default  => sub { Factory->new },
);

sub run_fixtures {
    my $table = shift;
    my $fixture;
    do { 
        my $e = attempt { $fixture = $self->make_fixture($table) } $table;
        return if $e; # stop processing fixtures if can't create a fixture
    } while $table = $self->run_and_get_next($table, $fixture);
}

sub run_and_get_next {
    my ($table, $fixture) = @_;
    my $next_table;
    attempt { $next_table = $fixture->do_tables } $table;
    return $next_table;
}

# for benefit of FIT::Runner::Tally;
sub run_fixtures_silently { $self->run_fixtures(@_) }


=head1 NAME

FIT::Fixture::Runner - run a FIT fixture


=head1 SYNOPSIS

    use aliased 'FIT::Fixture::Runner';

    # run the fixtures in the test document starting at the first table
    Runner->new->run_fixtures( $document->first_table );

    # same but don't add test results to tally
    Runner->new->run_fixtures_silently($table);


=head1 DESCRIPTION

Create a fixture runner with no parameters, then run a fixture by calling C<run_fixtures()>,
with one parameter: a table from the document. This table and all following tables will be
run one by one.

=cut

